package dao;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import model.Meting;

/**
 *  De class MetingDAO is een Data Access Object waarmee de
 *  metingen tabel van de weer database kan worden gemanipuleerd.
 ** @author Tom Regelink
 */
public class MetingDAO {

	private PreparedStatement prst;
	private ResultSet rs;
	private Connection conn;

	private String qDeleteMeting;
	private String qMetingenByID;
	private String qMetingenByDate;
	private String qMetingByDate;
	private String qUpdateMeting;
	private String qNewMeting;

	/**
	 * Default Constructor
	 */
	public MetingDAO() {
		qMetingenByID = "SELECT * FROM metingen WHERE station_id=?";
		qDeleteMeting = "DELETE FROM metingen WHERE station_id=? AND datum=?";
		qMetingenByDate = "SELECT * FROM metingen WHERE station_id=? AND datum BETWEEN ? AND ?";
		qMetingByDate = "SELECT * FROM metingen WHERE station_id=? AND datum=?";
		qUpdateMeting = "UPDATE metingen SET station_id=?," + "datum=?,"
				+ "windrichting=?," + "gemWindsnelheid=?,"
				+ "maxWindsnelheid=?," + "minWindsnelheid=?,"
				+ "gemTemperatuur=?," + "maxTemperatuur=?,"
				+ "minTemperatuur=?," + "minTemperatuur10=?,"
				+ "gemLuchtdruk=?," + "maxLuchtdruk=?," + "minLuchtdruk=?,"
				+ "duurNeerslag=?," + "somNeerslag=? "
				+ "WHERE station_id=? AND datum=?";
		qNewMeting = "INSERT INTO metingen VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
	}

	/**
	 * De methode getMetingenVanStation(int station_id) vraagt alle
	 * metingen van het opgegeven station_id op. Deze metingen
	 * worden in een ArrayList terug gegeven aan de aanroeper
	 * 
	 * @param station_id
	 * @return
	 * @throws SQLException
	 */
	public ArrayList<Meting> getMetingenVanStation(int station_id)
			throws SQLException {
		ArrayList<Meting> metingen = new ArrayList<Meting>();
		Meting meting = null;

		conn = DBManager.getInstance().getConnection();

		try {
			conn.setAutoCommit(false);

			prst = conn.prepareStatement(qMetingenByID);
			prst.setInt(1, station_id);

			rs = prst.executeQuery();

			conn.commit();

			while (rs.next()) {

				int id = rs.getInt(1);
				Date datum = rs.getDate(2);
				int windrichting = rs.getInt(3);
				int gemWindsnelheid = rs.getInt(4);
				int maxWindsnelheid = rs.getInt(5);
				int minWindsnelheid = rs.getInt(6);
				int gemTemperatuur = rs.getInt(7);
				int maxTemperatuur = rs.getInt(8);
				int minTemperatuur = rs.getInt(9);
				int minTemperatuur10 = rs.getInt(10);
				int gemLuchtdruk = rs.getInt(11);
				int maxLuchtdruk = rs.getInt(12);
				int minLuchtdruk = rs.getInt(13);
				int duurNeerslag = rs.getInt(14);
				int somNeerslag = rs.getInt(15);
				meting = new Meting(id, datum, windrichting, gemWindsnelheid,
						maxWindsnelheid, minWindsnelheid, gemTemperatuur,
						maxTemperatuur, minTemperatuur, minTemperatuur10,
						gemLuchtdruk, maxLuchtdruk, minLuchtdruk, duurNeerslag,
						somNeerslag);
				metingen.add(meting);
			}
		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				throw e1;
			}
			e.printStackTrace();
			throw e;
		} finally {
			DBManager.getInstance().close();
		}

		return metingen;
	}

	/**
	 * Geeft 1 meting terug op basis van het opgegeven station_id en
	 * de datum
	 * 
	 * @param station_id
	 * @param datum
	 * @return
	 * @throws SQLException
	 */
	public Meting getMeting(int station_id, java.sql.Date datum)
			throws SQLException {
		Meting m = null;

		conn = DBManager.getInstance().getConnection();

		try {
			conn.setAutoCommit(false);

			prst = conn.prepareStatement(qMetingByDate);
			prst.setInt(1, station_id);
			prst.setDate(2, datum);

			rs = prst.executeQuery();

			conn.commit();

			if (rs.next()) {
				int id = rs.getInt(1);
				Date datum2 = rs.getDate(2);
				int windrichting = rs.getInt(3);
				int gemWindsnelheid = rs.getInt(4);
				int maxWindsnelheid = rs.getInt(5);
				int minWindsnelheid = rs.getInt(6);
				int gemTemperatuur = rs.getInt(7);
				int maxTemperatuur = rs.getInt(8);
				int minTemperatuur = rs.getInt(9);
				int minTemperatuur10 = rs.getInt(10);
				int gemLuchtdruk = rs.getInt(11);
				int maxLuchtdruk = rs.getInt(12);
				int minLuchtdruk = rs.getInt(13);
				int duurNeerslag = rs.getInt(14);
				int somNeerslag = rs.getInt(15);
				m = new Meting(id, datum2, windrichting, gemWindsnelheid,
						maxWindsnelheid, minWindsnelheid, gemTemperatuur,
						maxTemperatuur, minTemperatuur, minTemperatuur10,
						gemLuchtdruk, maxLuchtdruk, minLuchtdruk, duurNeerslag,
						somNeerslag);
			} else {
				System.err.println("Geen meting gevonden");
				System.err.println("Stationid: " + station_id + " - datum: "
						+ datum);
			}
		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				throw e1;
			}
			throw e;
		} finally {
			DBManager.getInstance().close();
		}

		return m;
	}

	/**
	 * Geeft een ArrayList van metingen terug van 1 station met
	 * metingen tussen de opgegeven begin en eind datum
	 * 
	 * @param station_id
	 * @param beginDatum
	 * @param eindDatum
	 * @return
	 * @throws SQLException
	 */
	public ArrayList<Meting> getMetingen(int station_id,
			java.sql.Date beginDatum, java.sql.Date eindDatum)
			throws SQLException {
		ArrayList<Meting> metingen = new ArrayList<Meting>();
		Meting meting = null;

		conn = DBManager.getInstance().getConnection();

		try {
			conn.setAutoCommit(false);

			prst = conn.prepareStatement(qMetingenByDate);
			prst.setInt(1, station_id);
			prst.setDate(2, beginDatum);
			prst.setDate(3, eindDatum);

			rs = prst.executeQuery();

			conn.commit();

			while (rs.next()) {

				int id = rs.getInt(1);
				Date datum = rs.getDate(2);
				int windrichting = rs.getInt(3);
				int gemWindsnelheid = rs.getInt(4);
				int maxWindsnelheid = rs.getInt(5);
				int minWindsnelheid = rs.getInt(6);
				int gemTemperatuur = rs.getInt(7);
				int maxTemperatuur = rs.getInt(8);
				int minTemperatuur = rs.getInt(9);
				int minTemperatuur10 = rs.getInt(10);
				int gemLuchtdruk = rs.getInt(11);
				int maxLuchtdruk = rs.getInt(12);
				int minLuchtdruk = rs.getInt(13);
				int duurNeerslag = rs.getInt(14);
				int somNeerslag = rs.getInt(15);
				meting = new Meting(id, datum, windrichting, gemWindsnelheid,
						maxWindsnelheid, minWindsnelheid, gemTemperatuur,
						maxTemperatuur, minTemperatuur, minTemperatuur10,
						gemLuchtdruk, maxLuchtdruk, minLuchtdruk, duurNeerslag,
						somNeerslag);
				metingen.add(meting);
			}
		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				throw e1;
			}
			e.printStackTrace();
			throw e;
		} finally {
			DBManager.getInstance().close();
		}

		return metingen;
	}

	/**
	 * Verwijdert een meting uit de tabel met metingen
	 * 
	 * @param station_id
	 * @param datum
	 * @throws SQLException
	 */
	public void deleteMeting(int station_id, java.sql.Date datum)
			throws SQLException {
		
		conn = DBManager.getInstance().getConnection();
		try {
			conn.setAutoCommit(false);

			prst = conn.prepareStatement(qDeleteMeting);
			prst.setInt(1, station_id);
			prst.setDate(2, datum);
			prst.execute();

			conn.commit();

		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				throw e1;
			}
			e.printStackTrace();
			throw e;
		} finally {
			DBManager.getInstance().close();
		}
	}

	/**
	 * Op basis van het oude station_id en datum (mits verandert)
	 * worden de waarden uit het Meting object in de database
	 * geplaatst.
	 * 
	 * @param station_id
	 * @param datum
	 * @param m
	 * @throws SQLException
	 */
	public void updateMeting(int station_id, java.sql.Date datum, Meting m)
			throws SQLException {

		conn = DBManager.getInstance().getConnection();

		try {
			conn.setAutoCommit(false);

			prst = conn.prepareStatement(qUpdateMeting);

			prst.setInt(1, m.getStation_id());
			prst.setDate(2, (new java.sql.Date(m.getDatum().getTime())));
			prst.setInt(3, m.getWindrichting());
			prst.setInt(4, m.getGemWindsnelheid());
			prst.setInt(5, m.getMaxWindsnelheid());
			prst.setInt(6, m.getMinWindsnelheid());
			prst.setInt(7, m.getGemTemperatuur());
			prst.setInt(8, m.getMaxTemperatuur());
			prst.setInt(9, m.getMinTemperatuur());
			prst.setInt(10, m.getMinTemperatuur10());
			prst.setInt(11, m.getGemLuchtdruk());
			prst.setInt(12, m.getMaxLuchtdruk());
			prst.setInt(13, m.getMinLuchtdruk());
			prst.setInt(14, m.getDuurNeerslag());
			prst.setInt(15, m.getSomNeerslag());

			prst.setInt(16, station_id);
			prst.setDate(17, datum);

			prst.executeUpdate();

			conn.commit();

		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				throw e1;
			}
			throw e;
		} finally {
			DBManager.getInstance().close();
		}
	}

	public void newMeting(Meting m) throws SQLException {

		conn = DBManager.getInstance().getConnection();

		try {
			conn.setAutoCommit(false);

			prst = conn.prepareStatement(qNewMeting);

			prst.setInt(1, m.getStation_id());
			prst.setDate(2, (new java.sql.Date(m.getDatum().getTime())));
			prst.setInt(3, m.getWindrichting());
			prst.setInt(4, m.getGemWindsnelheid());
			prst.setInt(5, m.getMaxWindsnelheid());
			prst.setInt(6, m.getMinWindsnelheid());
			prst.setInt(7, m.getGemTemperatuur());
			prst.setInt(8, m.getMaxTemperatuur());
			prst.setInt(9, m.getMinTemperatuur());
			prst.setInt(10, m.getMinTemperatuur10());
			prst.setInt(11, m.getGemLuchtdruk());
			prst.setInt(12, m.getMaxLuchtdruk());
			prst.setInt(13, m.getMinLuchtdruk());
			prst.setInt(14, m.getDuurNeerslag());
			prst.setInt(15, m.getSomNeerslag());

			prst.execute();

			conn.commit();

		} catch (SQLException e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				throw e1;
			}
			throw e;
		} finally {
			DBManager.getInstance().close();
		}
	}
}
